package com.zusmart.core.interceptor;

import java.lang.reflect.Method;

import com.zusmart.core.proxy.ProxyChain;
import com.zusmart.core.proxy.ProxyFactory;

public abstract class InterceptorFactory implements ProxyFactory {

	@Override
	public Object execute(ProxyChain proxyChain) throws Throwable {
		Object result = null;
		Class<?> targetClass = proxyChain.getTargetClass();
		Method targetMethod = proxyChain.getTargetMethod();
		Object[] arguments = proxyChain.getTargetArguments();
		if (this.onIntercept(targetClass, targetMethod, arguments)) {
			this.onBefore(targetClass, targetMethod, arguments);
			try {
				result = proxyChain.doProxyChain();
			} catch (Throwable t) {
				this.onException(targetClass, targetMethod, arguments, t);
			}
			this.onAfter(targetClass, targetMethod, arguments, result);
		} else {
			try {
				result = proxyChain.doProxyChain();
			} catch (Throwable t) {
				this.onException(targetClass, targetMethod, arguments, t);
			}
		}
		return result;
	}

	/**
	 * 判断当前方法是否需要拦截，默认返回true，自定义可重写此方法
	 * 
	 * @param targetClass
	 *            目标class
	 * @param targetMethod
	 *            目标method
	 * @param arguments
	 *            方法调用参数
	 * @return true为拦截
	 * @throws Throwable
	 *             可能出现的异常
	 */
	protected boolean onIntercept(Class<?> targetClass, Method targetMethod, Object[] arguments) throws Throwable {
		return true;
	}

	/**
	 * 方法调用前执行
	 * 
	 * @param targetClass
	 *            目标class
	 * @param targetMethod
	 *            目标method
	 * @param arguments
	 *            方法调用参数
	 * @throws Throwable
	 *             可能出现的异常
	 */
	protected void onBefore(Class<?> targetClass, Method targetMethod, Object[] arguments) throws Throwable {
	}

	/**
	 * 方法调用后执行
	 * 
	 * @param targetClass
	 *            目标class
	 * @param targetMethod
	 *            目标method
	 * @param arguments
	 *            方法调用参数
	 * @param result
	 *            上一个拦截器的返回结果
	 * @throws Throwable
	 *             可能出现的异常
	 */
	protected void onAfter(Class<?> targetClass, Method targetMethod, Object[] arguments, Object result) throws Throwable {
	}

	/**
	 * 方法调用出现异常执行
	 * 
	 * @param targetClass
	 *            目标class
	 * @param targetMethod
	 *            目标method
	 * @param arguments
	 *            方法调用参数
	 * @param exception
	 *            出现的异常
	 */
	protected void onException(Class<?> targetClass, Method targetMethod, Object[] arguments, Throwable exception) {
	}

}